/*
 * HttpServiceUtil.cpp
 *
 *  Created on: 2019年11月29日
 *      Author: terry
 */

#include "HttpServiceUtil.h"
#include <algorithm>
#include "AppConst.h"
#include "TStringUtil.h"
#include "JsonUtil.h"


HttpServiceUtil::HttpServiceUtil()
{
}

HttpServiceUtil::~HttpServiceUtil()
{
}

bool HttpServiceUtil::parseJson(const char* str, size_t len, Json::Value& json)
{
	Json::CharReaderBuilder builder;
	builder["collectComments"] = false;
	Json::CharReader* reader = builder.newCharReader();
	JSONCPP_STRING errs;
	bool done = reader->parse(str, str + len, &json, &errs);
	delete reader;

	return done;
}

bool HttpServiceUtil::bodyAsJson(HttpRequest& request, Json::Value& json)
{
	size_t len = 0;
	const char* str = request.getBody(len);
	return parseJson(str, len, json);
}

int HttpServiceUtil::getSearchParams(HttpRequest& request, int& offset)
{
    int limit = AppConst::PAGE_SIZE;
	checkGet(request, "pageSize", "limit", limit);

    if (limit < 0)
    {
        limit = AppConst::PAGE_SIZE;
    }

    int page = 0;
	if (checkGet(request, "pageIndex", "page", page))
	{
		page = std::max(1, page);
		offset = (page - 1) * limit;
	}
	else if (request.get("offset", offset))
	{
	}
	else
	{
		//
	}

    return limit;
}


int HttpServiceUtil::parseEnabled(HttpRequest& request, EnabledItems& items)
{
	EnabledItem item;
	if (request.get("id", item.first) && request.get("enabled", item.second))
	{
		items.push_back(item);
		return 1;
	}

	int count = 0;
	Json::Value json;
	if (bodyAsJson(request, json))
	{
		if (json.isArray())
		{
			for (Json::ArrayIndex i = 0; i < json.size(); ++i)
			{
				Json::Value& itemJson = json[i];
				if (itemJson.isMember("id") && itemJson.isMember("enabled"))
				{
					EnabledItem item;
					item.first = itemJson["id"].asString();
					item.second = itemJson["enabled"].asBool();
					items.push_back(item);

					count ++;
				}
			}
		}
	}
	return count;
}

int HttpServiceUtil::parseIds(HttpRequest& request, StringArray& ids)
{
	std::string id;
	if (request.get("id", id))
	{
		return (int)comn::StringUtil::split(id, ',', ids);
	}

	int count = 0;
	Json::Value json;
	if (bodyAsJson(request, json))
	{
		if (json.isArray())
		{
			for (Json::ArrayIndex i = 0; i < json.size(); ++i)
			{
				Json::Value& itemJson = json[i];
				if (itemJson.isString())
				{
					std::string id = itemJson.asString();
					if (id.size() > 0)
					{
						ids.push_back(id);
						count ++;
					}
				}
			}
		}
		else if (json.isObject())
		{
			Json::Value child;
			if (Json::optGetArray(json, "ids", child))
			{
				count = Json::toStringArray(child, ids);
			}
		}
	}
    return count;
}

int HttpServiceUtil::parseIds(HttpRequest& request, IntArray& ids)
{
	std::string str;
	if (request.get("id", str))
    {
		StringArray idArray;
		int count = (int)comn::StringUtil::split(str, ',', idArray);
		for (const std::string& id : idArray)
		{
			IntArray::value_type item = IntArray::value_type();
			comn::StringCast::toValue(id, item);
			ids.push_back(item);
		}
		return count;
    }

    int count = 0;
    Json::Value json;
	if (bodyAsJson(request, json))
    {
        if (json.isArray())
        {
			count = Json::toIntArray(json, ids);
        }
		else if (json.isObject())
		{
			Json::Value child;
			if (Json::optGetArray(json, "ids", child))
			{
				count = Json::toIntArray(child, ids);
			}
		}
    }
    return count;
}

int HttpServiceUtil::parseIds(HttpRequest& request, Int64Array& ids)
{
	std::string str;
	if (request.get("id", str))
	{
		StringArray idArray;
		int count = (int)comn::StringUtil::split(str, ',', idArray);
		for (const std::string& id : idArray)
		{
			Int64Array::value_type item = Int64Array::value_type();
			comn::StringCast::toValue(id, item);
			ids.push_back(item);
		}
		return count;
	}

	int count = 0;
	Json::Value json;
	if (bodyAsJson(request, json))
	{
		if (json.isArray())
		{
			count = Json::toIntArray(json, ids);
		}
		else if (json.isObject())
		{
			Json::Value child;
			if (Json::optGetArray(json, "ids", child))
			{
				count = Json::toIntArray(child, ids);
			}
		}
	}
	return count;
}

bool HttpServiceUtil::parseBody(HttpRequest& request, StringArray& strList)
{
    bool found = false;
    Json::Value json;
	if (bodyAsJson(request, json))
    {
        if (json.isArray())
        {
			Json::toStringArray(json, strList);

            found = true;
        }
    }
    return found;
}

bool HttpServiceUtil::checkGet(HttpRequest& request, const char* name, const char* optName, int& value)
{
	bool got = request.get(name, value);
	if (!got)
	{
		got = request.get(optName, value);
	}
	return got;
}

bool HttpServiceUtil::getRemoteAddr(HttpServer* server, HttpRequest& request, std::string& ip, int& port)
{
	std::string name;
	bool got = server->getRemoteAddr(request.getConnection(), name);
	if (got)
	{
		if (!comn::StringUtil::split(name, ':', ip, port))
		{
			ip = name;
		}
	}
	return got;
}